use tracing_appender::{non_blocking, rolling};
use std::error::Error;
use std::result;
use tracing_error::ErrorLayer;
use tracing_subscriber::{fmt, layer::SubscriberExt, util::SubscriberInitExt, Layer, Registry};
use tracing_subscriber::fmt::time::FormatTime;
use tracing_subscriber::fmt::format::Writer;
use crate::config::{LogConfig, RollType,LogLevel};
use chrono::prelude::*;

pub struct MyTime;

type FmtError = std::fmt::Error;

impl FormatTime for MyTime {
    fn format_time(&self, w: &mut Writer<'_>) -> result::Result<(), FmtError> {     
        let now = Local::now().format("%Y-%m-%d %H:%M:%S%.6f").to_string();
        write!(w,"{}", now)
    }
}


pub fn logger_init(conf:LogConfig) -> Result<tracing_appender::non_blocking::WorkerGuard,Box<dyn Error>> {
    
	// 文件输出层
	let file_appender;
    match  conf.roll {
        RollType::Daily => {
            file_appender = rolling::daily(conf.out_dir, conf.file_prefix);
        },
        _ => {
            file_appender = rolling::never(conf.out_dir, conf.file_prefix);
        }
    }

    let max_level;
    match conf.level {
        LogLevel::Trace => {
            max_level = tracing_subscriber::filter::LevelFilter::TRACE;
        },
        LogLevel::Debug => {
            max_level = tracing_subscriber::filter::LevelFilter::DEBUG;
        },
        LogLevel::Info => {
            max_level = tracing_subscriber::filter::LevelFilter::INFO;
        },
        LogLevel::Warn => {
            max_level = tracing_subscriber::filter::LevelFilter::WARN;
        },
        LogLevel::Error => {
            max_level = tracing_subscriber::filter::LevelFilter::ERROR;
        },
        LogLevel::Final => {
            max_level = tracing_subscriber::filter::LevelFilter::ERROR;
        },
        LogLevel::None => {
            max_level = tracing_subscriber::filter::LevelFilter::OFF;
        },
    }

    // let format = "[year]-[month]-[day] [hour]:[minute]:[second].[subsecond digits:3]";

    //let timer = LocalTime::new(format_description!("[hour]:[minute]:[second]"));

    let (non_blocking_appender, _guard) = non_blocking(file_appender); // 输出非阻塞
    let file_layer = fmt::layer()
         .with_timer(MyTime)
         .with_ansi(false)
         .with_writer(non_blocking_appender)
         .with_filter(max_level) // 文件输出日志等级
       
         .boxed();

    let formatting_layer = fmt::layer().pretty().with_timer(MyTime).with_writer(std::io::stdout).with_filter(tracing_subscriber::filter::LevelFilter::DEBUG);

    
    Registry::default().with(ErrorLayer::default())
    .with(file_layer).with(formatting_layer).init();

    Ok(_guard)
    // // color_eyre::install().unwrap();
}